#include "sstf.h"
#include "ui_sstf.h"
#define WIDTH 1200
#define HEIGHT 800
#define LENGTH 400
#define TOTAL_STATION 9
#define DISTANCE 2

QVector<QString>head;
QVector<QVector<int>> array; //输出的数组
QVector<QVector<int>> waittime; //等待时间
QVector<QVector<int>> order;
int cur=1;
int curtime; //计时器
int sign=0;
int destination=-1;
int limit=TOTAL_STATION*DISTANCE-1;
bus Bus;
QString s;

int x_1 = 100;
int y_1 = 180;
int x_2 = x_1 + LENGTH;
int y_2 = y_1 + LENGTH;
int distance = LENGTH * 4 / (TOTAL_STATION * DISTANCE);
int bus_x = x_1;
int bus_y = y_1;



//构造函数
SSTF::SSTF(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SSTF)
{
    ui->setupUi(this);
    ui->bus->installEventFilter(this);
    setFixedSize(1200,800);
    //创建数组，并完成初始化
    array.resize(3);
    for(int j=0;j<array.size();j++)
    {
        array[j].resize(TOTAL_STATION+2);
    }
    waittime.resize(3);
    for(int j=0;j<waittime.size();j++)
    {
        waittime[j].resize(TOTAL_STATION);
    }
    order.resize(3);
    for(int j=0;j<order.size();j++)
    {
        order[j].resize(TOTAL_STATION+2);
    }
    //设置当前时间
    curtime=0;
    destination=ShortSearch(order);



    //label中填充图片
    QImage Image;
    Image.load(":/img/bus.png");
    QPixmap pixmap = QPixmap::fromImage(Image);
    int with = ui->label->width();
    int height = ui->label->height();
    QPixmap fitpixmap = pixmap.scaled(with, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);  // 按比例缩放
    ui->label->setPixmap(fitpixmap);
    ui->label->move(QPoint(bus_x,bus_y));
    ui->state->setText("等待请求中...");
    QPixmap p;
    p.load(":/img/flower.png");
    p.scaled(ui->icon->size(), Qt::KeepAspectRatio);
    ui->icon->setScaledContents(true);
    ui->icon->setPixmap(p);


    //链接槽函数和信号（点击按钮将文本框中输入的内容取得）
    connect(ui->TButton,&QPushButton::clicked,this,&SSTF::TchangArr);
    connect(ui->CButton,&QPushButton::clicked,this,&SSTF::CchangArr);
    connect(ui->UButton,&QPushButton::clicked,this,&SSTF::UchangArr);
    //设置定时器
    startTimer(1500);
}

//下面两个函数用于在左侧的label中绘制矩形，在画边界的时候比较费脑子
bool SSTF::eventFilter(QObject *watched, QEvent *event) {
    if (watched == ui->bus && event->type() == QEvent::Paint) {
        paintbus();
    }
    return QWidget::eventFilter(watched, event);
}

void SSTF::paintbus() {

    QPainter painter(ui->bus);

    //绘制矩形
    QPen pen(QColor(200, 200, 200));
    pen.setWidth(7);
    painter.setPen(pen);
    int margin_left=100;
    int margin_top=(HEIGHT-LENGTH)/2;
    QRectF rectangle(margin_left,margin_top, LENGTH, LENGTH);  //坐标，宽高
    painter.drawRect(rectangle);
    //绘制上面的点
    int x=margin_left;
    int y=margin_top;
    int flag=1;
    for(int i=0;i<TOTAL_STATION * DISTANCE; i++)
    {
        if (i % DISTANCE)
        {
            painter.setPen(QColor(Qt::black));
            painter.setBrush(QBrush(Qt::black));
            painter.drawEllipse(x-4,y-4,7,7);
        }
        else {
            painter.setPen(QColor(Qt::red));
            painter.setBrush(QBrush(Qt::red));
            painter.drawEllipse(x-4,y-4,13,13);
        }

        if(flag==1&&LENGTH-(x-margin_left)<=distance){
            y+=distance-(LENGTH-(x-margin_left));
            x=margin_left+LENGTH;
            flag=2;

        }
        else if(flag==1&&LENGTH-(x-margin_left)>distance){
            x+=distance;

        }
        else if(flag==2&&LENGTH-(y-margin_top)<=distance)
        {
            x-=distance-(LENGTH-(y-margin_top));
            y=margin_top+LENGTH;
            flag=3;
        }
        else if(flag==2&&LENGTH-(y-margin_top)>distance)
        {
            y+=distance;
        }
        else if(flag==3&&(x-margin_left)<=distance)
        {
            y-=distance-(x-margin_left);
            x=margin_left;
            flag=4;
        }
        else if(flag==3&&(x-margin_left)>distance)
        {
            x-=distance;
        }
        else if(flag==4&&(y-margin_top)<=distance){
            y=margin_top;
            x+=distance-((y-margin_top));
            flag=1;
        }
        else if(flag==4&&(y-margin_top)>distance){
            y-=distance;
        }
    }
}

int SSTF::ShortSearch(QVector<QVector<int> > order)//因为是在处理掉目标地所有服务再调用，杜绝了当前位置处有服务
{
    int cur=Bus.position/DISTANCE+1;//现在位置
    int i=cur+1;
    int left=10,right=10;//设置一个正常无法达到的顶值
    int time1=1000,time2=1000;//设置一个正常无法达到的顶值，此为暂存的次序
    while(i!=cur)
    {
        if(i>TOTAL_STATION)
            i=1;
        if(i==cur)
            break;
        if(array[0][i-1]==1||array[1][i-1]==1||array[2][i-1]==1)
        {
            if(right==10)
            {
                right=i>cur?(i-cur):(TOTAL_STATION-cur+i);//选择返回右距离
                if(array[0][i-1]==1)
                    time1=order[2][i-1];
                if(array[1][i-1]==1)
                    time1=order[0][i-1];
                if(array[2][i-1]==1)
                    time1=order[1][i-1];
            }
            left=i>cur?(TOTAL_STATION-i+cur):(cur-i);//选择返回左距离
            if(array[0][i-1]==1)
                time2=order[2][i-1];
            if(array[1][i-1]==1)
                time2=order[0][i-1];
            if(array[2][i-1]==1)
                time2=order[1][i-1];
        }
        i++;
    }
    if(left>right||(left==right&&right!=10&&time1<=time2))//包括了同一目标的顺时针优先和单一目标的时间比较
    {
        Bus.direction=1;
        i=(cur+right)<=TOTAL_STATION?(cur+right):(cur+right-TOTAL_STATION);
        return i;
    }
    else if(right>left||(left==right&&right!=10&&time1>=time2))
    {
        Bus.direction=2;
        i=(cur-left)>0?(cur-left):(TOTAL_STATION+cur-left);
        return i;
    }
    else//(left==right&&right==10)
    {
        Bus.direction=0;
        Bus.status=0;
        return -1;
    }
}

//点击按钮后收到数据并改变对应二进制数组
void SSTF::TchangArr(){
    QString temp=ui->Tedit->text();
    int station_num=temp.toInt();
    if(Bus.status==0&&(station_num==cur))
        ;
    else
    {
        if(array[0][station_num-1]==0)
        {
            array[0][station_num-1]=1;
            waittime[2][station_num-1]=curtime;
            sign++;
            order[2][station_num-1]=sign;
            //下面那个else不知道需要加吗
            update();
        }
        if(destination==-1)
        {
            destination=ShortSearch(order);
            Bus.status=1;
        }
    }
    ui->Tedit->clear();
}
void SSTF::CchangArr(){
    QString temp=ui->Cedit->text();
    int station_num=temp.toInt();
    if(Bus.status==0&&(station_num==cur)&&Bus.direction!=2)//包括目标停和顺便停
        ;
    else
    {
        if(array[1][station_num-1]==0)
        {
            array[1][station_num-1]=1;
            waittime[0][station_num-1]=curtime;
            sign++;
            order[0][station_num-1]=sign;
            update();
        }
        if(destination==-1)
        {
            destination=ShortSearch(order);
            Bus.status=1;
        }
    }
    ui->Cedit->clear();
}
void SSTF::UchangArr(){
    QString temp=ui->Uedit->text();
    int station_num=temp.toInt();
    if(Bus.status==0&&(station_num==cur)&&Bus.direction!=1)
        ;
    else
    {
        if(array[2][station_num-1]==0)
        {array[2][station_num-1]=1;
            waittime[1][station_num-1]=curtime;
            sign++;
            order[1][station_num-1]=sign;
            update();
        }
        if(destination==-1)
        {
            destination=ShortSearch(order);
            Bus.status=1;
        }
    }
    ui->Uedit->clear();
}

//定时器
void SSTF::timerEvent(QTimerEvent *)
{
    curtime++;
    update();

}
//更新时间数组，
void SSTF::update(){
    curtime++;//还未实装waittime具体输出部分
    Bus.status=1;//放在这里是修正为在收到服务时立即解决掉，避免1秒原则
    if(destination==-1)//说明因为无服务停止了，必在站点处
    {
        destination=ShortSearch(order);
    }//判断是否有可进行的请求
    else if(Bus.position % DISTANCE==0)
    {
        cur=Bus.position/DISTANCE+1;
        if(cur!=destination)//判断顺便服务并处理
        {
            if(Bus.direction==1)//区分方向，因为是二的顺便
            {
                if(array[0][cur-1]==1||array[1][cur-1]==1)
                {
                    if((curtime-1)>waittime[0][cur-1]&&array[1][cur-1]==1)
                    {waittime[0][cur-1]=0;//暂时设置为记录开始时间较优
                        Bus.status=0;
                        array[1][cur-1]=0;}
                    if((curtime-1)>waittime[2][cur-1]&&array[0][cur-1]==1)
                    {array[0][cur-1]=0;
                        Bus.status=0;
                        waittime[2][cur-1]=0;}
                }
            }
            else if(Bus.direction==2)
            {
                if(array[0][cur-1]==1||array[2][cur-1]==1)
                {
                    if((curtime-1)>waittime[1][cur-1]&&array[2][cur-1]==1)
                    {waittime[1][cur-1]=0;//暂时设置为记录开始时间较优
                        Bus.status=0;
                        array[2][cur-1]=0;}
                    if((curtime-1)>waittime[2][cur-1]&&array[0][cur-1]==1)
                    {waittime[2][cur-1]=0;
                        Bus.status=0;
                        array[0][cur-1]=0;}
                     ui->state->setText("到站了,停车等待");
                }
            }
        }
        else                          //判断目标站并处理
        {
            waittime[0][cur-1]=0;
            waittime[1][cur-1]=0;
            waittime[2][cur-1]=0;
            array[0][cur-1]=0;
            array[1][cur-1]=0;
            array[2][cur-1]=0;
            Bus.status=0;
             ui->state->setText("到站了,停车等待");
            destination=ShortSearch(order);//重新判断方向和目标。考虑的是完成后吸取此一秒的请求后再调度新目标
        }
    }
    if(Bus.status!=0)
    {
        ui->state->setText("车辆行驶中...");
        //车子移动
        //如果是1（顺时针）
        if(Bus.direction==1)
        {
            Bus.position++;
            shunshizhen();
        }

        else{
            Bus.position--;
            nishizhen();
        }
        if(Bus.position>limit)
            Bus.position=0;
        if(Bus.position<0)
            Bus.position=limit;
    }//注意边界情况
    output();
}


void SSTF::shunshizhen()
{
    if(bus_y==y_1){
        if(x_2-bus_x>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_x+=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else {
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            anim->setKeyValueAt(0.5,QPoint(x_2,y_1));
            bus_y+=distance-(x_2-bus_x);
            bus_x=x_2;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
    }
    else if(bus_x==x_2){
        if(y_2-bus_y>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y+=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else{
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y=y_2;
            bus_x-=distance-(y_2-bus_y);
            anim->setKeyValueAt(0.5,QPoint(x_2,y_2));
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
    }
    else if(bus_y==y_2){
        if(bus_x-x_1>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_x-=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else{
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y -= distance - (bus_x - x_1);
            bus_x=x_1;
            anim->setKeyValueAt(0.5,QPoint(x_1,y_2));
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
    }
    else if(bus_x==x_1){
        if(bus_y-y_1>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y-=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else{
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y=y_1;
            bus_x+=distance-(bus_y-y_1);
            anim->setKeyValueAt(0.5,QPoint(x_1,y_1));
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
    }

}
void SSTF::nishizhen(){
    if (Bus.position == 0)
    { //到左边的边界
        Bus.position = DISTANCE * TOTAL_STATION - 1;
    }
    else
        Bus.position--;
    if(bus_y==y_1){
        if(bus_x-x_1>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_x-=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else {
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            anim->setKeyValueAt(0.5,QPoint(x_1,y_1));
            bus_y+=distance-(bus_x-x_1);
            bus_x=x_1;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
    }
    else if(bus_x==x_1){
        if(y_2-bus_y>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y+=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else{
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_x+=distance-(y_2-bus_y);
            bus_y=y_2;
            anim->setKeyValueAt(0.5,QPoint(x_1,y_2));
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
    }
    else if(bus_y==y_2){
        if(x_2-bus_x>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_x+=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else{
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y -= distance - (x_2-bus_x);
            bus_x=x_2;
            anim->setKeyValueAt(0.5,QPoint(x_2,y_2));
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
    }
    else if(bus_x==x_2){
        if(bus_y-y_1>distance){
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_y-=distance;
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }
        else{
            QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
            anim->setDuration(1000);
            anim->setStartValue(QPoint(bus_x,bus_y));
            bus_x-=distance-(bus_y-y_1-3); //这点是为了让图标对齐
            bus_y=y_1;
            anim->setKeyValueAt(0.5,QPoint(x_2,y_1));
            anim->setEndValue(QPoint(bus_x,bus_y));
            anim->start();
        }


    }
}
//输出
void SSTF::output(){
    static QString s;  //输出的字符串，将数组转化为字符串后输出在label中
    s="";
    head={"target:","clockwise:","counterclockwise:"};
    s+=QString("TIME:%1%2").arg(curtime).arg("\n");
    for(int i = 0; i < array.size(); i++)
    {
        s+=head[i];
        for (int  j= 0; j < TOTAL_STATION;j++)
        {
            QString temp;
            temp.setNum(array[i][j]);
            s+=temp;
        }
        s+="\n";
    }
    ui->output_label->setText(s);

    QString b;
    b=QString::number(Bus.position);
    ui->pos->setText(b);
}


//析构函数
SSTF::~SSTF()
{
    delete ui;
}

